/*
 * BaseRequest.java
 * business
 *
 * Created by ChenTao on 2016/9/9.
 *
 * Copyright (c) 2016年 yidiandao. All rights reserved.
 */

package com.yidiandao.business.data.net;

import android.support.v4.util.ArrayMap;
import android.text.TextUtils;

import com.google.gson.Gson;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import com.yidiandao.business.constant.Common;
import com.yidiandao.business.constant.Urls;
import com.yidiandao.business.utils.GsonProvider;
import com.yidiandao.business.utils.Md5Utils;
import com.yidiandao.business.utils.PreferenceUtils;
import com.yidiandao.business.utils.UrlUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 服务端接口请求参数的基类.
 */
public class BaseRequest {

    protected String tag;
    @Expose
    protected String url;

    @Expose
    @SerializedName("token")
    private String token;

    @Expose
    @SerializedName("app_version")
    private String appVersion;
    /**
     * 请求体的Map集合
     */
    private ArrayMap<String, String> requestMap = new ArrayMap<>();

    /**
     * 将请求信息转换为json.
     *
     * @return 接口的关键信息
     */
    public String toJson() {
        // 只生成有expose注释的文件
        Gson gson = GsonProvider.getExposeGson();
        return gson.toJson(this);
    }

    public String getToken() {
        return token;
    }

    public void setToken(String token) {
        if (PreferenceUtils.STRING_DEFAULT.equals(token) || TextUtils.isEmpty(token)) {
            // token无效（为空）
            return;
        }
        this.token = token;
    }

    public String getUrl() {
        return url;
    }

    /**
     * 需要拼接host
     *
     * @param url
     */
    public void setUrl(String url) {
        if (url.equals(Urls.LOCATION_DOMAIN) || url.equals(Urls.GET_CITY_LIST)) {
            this.url = UrlUtils.getDefaultUrl(url);
        } else {
            this.url = UrlUtils.getTrulyUrl(url);
        }
    }

    /**
     * 直接使用  不需拼接host
     *
     * @param url
     */
    public void setDirectUrl(String url) {
        this.url = url;
    }

    String getAppVersion() {
        return appVersion;
    }

    void setAppVersion(String appVersion) {
        this.appVersion = appVersion;
    }

    /**
     * 获取请求<String,String>的Map集合
     */
    Map<String, String> getRequestMap() {
        return getStringMap(this.getClass());
    }

    private Map<String, String> getStringMap(Class clazz) {
        for (Field field : clazz.getDeclaredFields()) {
            SerializedName name = field.getAnnotation(SerializedName.class);
            if (name != null) {
                try {
                    field.setAccessible(true);
                    if (field.getType() == String.class && field.get(this) == null) {
                        // 当前注解上没有值，跳出继续循环
                        continue;
                    }
                    requestMap.put(name.value(), String.valueOf(field.get(this)));
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }

        // 获取父类上的请求体集合
        Class superClazz = clazz.getSuperclass();
        if (superClazz != null) {
            getStringMap(superClazz);
        }
        return requestMap;
    }

    /**
     * 返回Header中添加的ReqToken
     */
    String getReqTokenString() {

        // 拼接时 加入时间戳
        long timestamp = System.currentTimeMillis();

        requestMap.put("timestamp", timestamp + "");

        Set<String> keySet = requestMap.keySet();

        // 字典序
        List<String> sortKeys = new ArrayList<>(keySet);
        Collections.sort(sortKeys);

        StringBuilder sb = new StringBuilder();

        for (String key : sortKeys) {

            String value = requestMap.get(key);
            sb.append(key);
            sb.append("=");
            sb.append(value);
            sb.append("&");
        }

        sb.append("key=");
        sb.append(Common.SERVER_KEY);

        String secret = Md5Utils.getMD5(sb.toString()).toUpperCase();

        return timestamp + "," + secret;
    }

    public String getTag() {
        return tag;
    }

    public void setTag(String tag) {
        this.tag = tag;
    }
}
